<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>功能分支工作流 | 我的笔记</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/notebook/favicon.ico">
    <script data-ad-client="ca-pub-4147143076931995" async="true" src="/notebook//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
    <meta name="description" content="方便阅读和寻找">
    
    <link rel="preload" href="/notebook/assets/css/0.styles.cee65b40.css" as="style"><link rel="preload" href="/notebook/assets/js/app.400f01da.js" as="script"><link rel="preload" href="/notebook/assets/js/2.ffba27f2.js" as="script"><link rel="preload" href="/notebook/assets/js/14.3ed225c4.js" as="script"><link rel="prefetch" href="/notebook/assets/js/10.9da57264.js"><link rel="prefetch" href="/notebook/assets/js/100.8aa79850.js"><link rel="prefetch" href="/notebook/assets/js/101.f8819976.js"><link rel="prefetch" href="/notebook/assets/js/102.7168e4aa.js"><link rel="prefetch" href="/notebook/assets/js/103.e1f049f7.js"><link rel="prefetch" href="/notebook/assets/js/104.0ada8567.js"><link rel="prefetch" href="/notebook/assets/js/105.77e95b95.js"><link rel="prefetch" href="/notebook/assets/js/106.9071202a.js"><link rel="prefetch" href="/notebook/assets/js/107.a0a63241.js"><link rel="prefetch" href="/notebook/assets/js/108.93ccf0bf.js"><link rel="prefetch" href="/notebook/assets/js/109.57caff98.js"><link rel="prefetch" href="/notebook/assets/js/11.d9d769c3.js"><link rel="prefetch" href="/notebook/assets/js/110.6aa16c3f.js"><link rel="prefetch" href="/notebook/assets/js/111.293e18e5.js"><link rel="prefetch" href="/notebook/assets/js/112.7f593e53.js"><link rel="prefetch" href="/notebook/assets/js/113.e03d7fe0.js"><link rel="prefetch" href="/notebook/assets/js/114.4fd73421.js"><link rel="prefetch" href="/notebook/assets/js/115.8dc5910d.js"><link rel="prefetch" href="/notebook/assets/js/116.fc5215b7.js"><link rel="prefetch" href="/notebook/assets/js/117.851bae37.js"><link rel="prefetch" href="/notebook/assets/js/118.03cb2186.js"><link rel="prefetch" href="/notebook/assets/js/119.17f93b7e.js"><link rel="prefetch" href="/notebook/assets/js/12.125d7a59.js"><link rel="prefetch" href="/notebook/assets/js/120.4ea767fb.js"><link rel="prefetch" href="/notebook/assets/js/121.483ad579.js"><link rel="prefetch" href="/notebook/assets/js/122.17d2596f.js"><link rel="prefetch" href="/notebook/assets/js/123.56e20e4e.js"><link rel="prefetch" href="/notebook/assets/js/124.2ec822f9.js"><link rel="prefetch" href="/notebook/assets/js/125.bccb84ed.js"><link rel="prefetch" href="/notebook/assets/js/126.e38a7466.js"><link rel="prefetch" href="/notebook/assets/js/127.43962ebd.js"><link rel="prefetch" href="/notebook/assets/js/128.23f8246b.js"><link rel="prefetch" href="/notebook/assets/js/129.e718e26c.js"><link rel="prefetch" href="/notebook/assets/js/13.f56b83ad.js"><link rel="prefetch" href="/notebook/assets/js/130.a51fe94d.js"><link rel="prefetch" href="/notebook/assets/js/131.64fb54a3.js"><link rel="prefetch" href="/notebook/assets/js/132.badc2a1a.js"><link rel="prefetch" href="/notebook/assets/js/133.72f12c19.js"><link rel="prefetch" href="/notebook/assets/js/134.0b1b2dc0.js"><link rel="prefetch" href="/notebook/assets/js/135.be2d740c.js"><link rel="prefetch" href="/notebook/assets/js/136.c3dc9ba1.js"><link rel="prefetch" href="/notebook/assets/js/137.784510e4.js"><link rel="prefetch" href="/notebook/assets/js/138.ff844e48.js"><link rel="prefetch" href="/notebook/assets/js/139.1ac43f97.js"><link rel="prefetch" href="/notebook/assets/js/140.4c427bf3.js"><link rel="prefetch" href="/notebook/assets/js/141.459f2cb4.js"><link rel="prefetch" href="/notebook/assets/js/142.e69e2b00.js"><link rel="prefetch" href="/notebook/assets/js/143.b9cd433a.js"><link rel="prefetch" href="/notebook/assets/js/144.c12cb09a.js"><link rel="prefetch" href="/notebook/assets/js/145.43e25cc4.js"><link rel="prefetch" href="/notebook/assets/js/146.0963c075.js"><link rel="prefetch" href="/notebook/assets/js/147.37f2e690.js"><link rel="prefetch" href="/notebook/assets/js/148.631fbe69.js"><link rel="prefetch" href="/notebook/assets/js/149.a22c5490.js"><link rel="prefetch" href="/notebook/assets/js/15.10a06d24.js"><link rel="prefetch" href="/notebook/assets/js/150.e6265d54.js"><link rel="prefetch" href="/notebook/assets/js/151.aefdb9fd.js"><link rel="prefetch" href="/notebook/assets/js/152.a8c722bd.js"><link rel="prefetch" href="/notebook/assets/js/153.ec2b1513.js"><link rel="prefetch" href="/notebook/assets/js/154.4fdc765f.js"><link rel="prefetch" href="/notebook/assets/js/155.de537bd1.js"><link rel="prefetch" href="/notebook/assets/js/156.7f87247c.js"><link rel="prefetch" href="/notebook/assets/js/157.f51afdd1.js"><link rel="prefetch" href="/notebook/assets/js/158.247f3f23.js"><link rel="prefetch" href="/notebook/assets/js/159.2342ec68.js"><link rel="prefetch" href="/notebook/assets/js/16.bc052b7f.js"><link rel="prefetch" href="/notebook/assets/js/160.98e33fe9.js"><link rel="prefetch" href="/notebook/assets/js/161.b8389795.js"><link rel="prefetch" href="/notebook/assets/js/162.5809ad21.js"><link rel="prefetch" href="/notebook/assets/js/163.6d40855f.js"><link rel="prefetch" href="/notebook/assets/js/164.cd5e8c28.js"><link rel="prefetch" href="/notebook/assets/js/165.c409d97c.js"><link rel="prefetch" href="/notebook/assets/js/166.75cd78fe.js"><link rel="prefetch" href="/notebook/assets/js/167.37552374.js"><link rel="prefetch" href="/notebook/assets/js/168.d4ab1d56.js"><link rel="prefetch" href="/notebook/assets/js/169.39f3c518.js"><link rel="prefetch" href="/notebook/assets/js/17.2a8873d5.js"><link rel="prefetch" href="/notebook/assets/js/170.7993242d.js"><link rel="prefetch" href="/notebook/assets/js/171.09f40b60.js"><link rel="prefetch" href="/notebook/assets/js/172.79168981.js"><link rel="prefetch" href="/notebook/assets/js/173.a75cd141.js"><link rel="prefetch" href="/notebook/assets/js/174.bd510afd.js"><link rel="prefetch" href="/notebook/assets/js/175.c3f8ba94.js"><link rel="prefetch" href="/notebook/assets/js/176.dd9cbd79.js"><link rel="prefetch" href="/notebook/assets/js/177.f53090f5.js"><link rel="prefetch" href="/notebook/assets/js/178.bcda53b0.js"><link rel="prefetch" href="/notebook/assets/js/179.2d510aa5.js"><link rel="prefetch" href="/notebook/assets/js/18.2d0a0d6d.js"><link rel="prefetch" href="/notebook/assets/js/180.6928e4f9.js"><link rel="prefetch" href="/notebook/assets/js/181.6cc94652.js"><link rel="prefetch" href="/notebook/assets/js/182.c7d6fde2.js"><link rel="prefetch" href="/notebook/assets/js/183.1a7eaa90.js"><link rel="prefetch" href="/notebook/assets/js/184.5d52b650.js"><link rel="prefetch" href="/notebook/assets/js/185.2f8eddcd.js"><link rel="prefetch" href="/notebook/assets/js/186.2615bcf2.js"><link rel="prefetch" href="/notebook/assets/js/187.ffb3009d.js"><link rel="prefetch" href="/notebook/assets/js/188.deef127e.js"><link rel="prefetch" href="/notebook/assets/js/189.51b1958b.js"><link rel="prefetch" href="/notebook/assets/js/19.482e846f.js"><link rel="prefetch" href="/notebook/assets/js/190.a5e85724.js"><link rel="prefetch" href="/notebook/assets/js/191.fd2dfc70.js"><link rel="prefetch" href="/notebook/assets/js/192.5cb3b141.js"><link rel="prefetch" href="/notebook/assets/js/193.3a6173b0.js"><link rel="prefetch" href="/notebook/assets/js/194.2b937e4b.js"><link rel="prefetch" href="/notebook/assets/js/195.71b1b3e2.js"><link rel="prefetch" href="/notebook/assets/js/196.d8d64ba1.js"><link rel="prefetch" href="/notebook/assets/js/197.fbea3131.js"><link rel="prefetch" href="/notebook/assets/js/198.25e90057.js"><link rel="prefetch" href="/notebook/assets/js/199.5bef52d0.js"><link rel="prefetch" href="/notebook/assets/js/20.3869e9c1.js"><link rel="prefetch" href="/notebook/assets/js/200.839b8484.js"><link rel="prefetch" href="/notebook/assets/js/201.dcc87a43.js"><link rel="prefetch" href="/notebook/assets/js/202.83abe52e.js"><link rel="prefetch" href="/notebook/assets/js/203.c8c886fe.js"><link rel="prefetch" href="/notebook/assets/js/204.7d91a0aa.js"><link rel="prefetch" href="/notebook/assets/js/205.dd934d84.js"><link rel="prefetch" href="/notebook/assets/js/206.ae9d7602.js"><link rel="prefetch" href="/notebook/assets/js/207.f5ac5260.js"><link rel="prefetch" href="/notebook/assets/js/208.203ba066.js"><link rel="prefetch" href="/notebook/assets/js/209.202991be.js"><link rel="prefetch" href="/notebook/assets/js/21.95b2d828.js"><link rel="prefetch" href="/notebook/assets/js/210.3e7c6db0.js"><link rel="prefetch" href="/notebook/assets/js/211.d231f4d5.js"><link rel="prefetch" href="/notebook/assets/js/212.74210f2c.js"><link rel="prefetch" href="/notebook/assets/js/213.ca497e10.js"><link rel="prefetch" href="/notebook/assets/js/214.256f2f8d.js"><link rel="prefetch" href="/notebook/assets/js/215.e5a91195.js"><link rel="prefetch" href="/notebook/assets/js/22.bfedf3cf.js"><link rel="prefetch" href="/notebook/assets/js/23.07416482.js"><link rel="prefetch" href="/notebook/assets/js/24.54aaf5dd.js"><link rel="prefetch" href="/notebook/assets/js/25.5fddfc47.js"><link rel="prefetch" href="/notebook/assets/js/26.3beace9a.js"><link rel="prefetch" href="/notebook/assets/js/27.8166fc8b.js"><link rel="prefetch" href="/notebook/assets/js/28.45eec4fe.js"><link rel="prefetch" href="/notebook/assets/js/29.7d2c15a3.js"><link rel="prefetch" href="/notebook/assets/js/3.58b1a014.js"><link rel="prefetch" href="/notebook/assets/js/30.a7841312.js"><link rel="prefetch" href="/notebook/assets/js/31.dc9675e8.js"><link rel="prefetch" href="/notebook/assets/js/32.93c6c35d.js"><link rel="prefetch" href="/notebook/assets/js/33.9a64b2f6.js"><link rel="prefetch" href="/notebook/assets/js/34.0c220f3c.js"><link rel="prefetch" href="/notebook/assets/js/35.9f407421.js"><link rel="prefetch" href="/notebook/assets/js/36.ee8ac781.js"><link rel="prefetch" href="/notebook/assets/js/37.569079d1.js"><link rel="prefetch" href="/notebook/assets/js/38.56b32d83.js"><link rel="prefetch" href="/notebook/assets/js/39.6ea9c955.js"><link rel="prefetch" href="/notebook/assets/js/4.5042ba18.js"><link rel="prefetch" href="/notebook/assets/js/40.5bdebc85.js"><link rel="prefetch" href="/notebook/assets/js/41.8607bd5a.js"><link rel="prefetch" href="/notebook/assets/js/42.2063b1d0.js"><link rel="prefetch" href="/notebook/assets/js/43.ff59782c.js"><link rel="prefetch" href="/notebook/assets/js/44.c40eaded.js"><link rel="prefetch" href="/notebook/assets/js/45.bc61bb49.js"><link rel="prefetch" href="/notebook/assets/js/46.e9ea5687.js"><link rel="prefetch" href="/notebook/assets/js/47.a9626a0e.js"><link rel="prefetch" href="/notebook/assets/js/48.9bf986fe.js"><link rel="prefetch" href="/notebook/assets/js/49.dd90158a.js"><link rel="prefetch" href="/notebook/assets/js/5.b9679d2a.js"><link rel="prefetch" href="/notebook/assets/js/50.a9546c5a.js"><link rel="prefetch" href="/notebook/assets/js/51.dcc646ec.js"><link rel="prefetch" href="/notebook/assets/js/52.111a35ff.js"><link rel="prefetch" href="/notebook/assets/js/53.19719081.js"><link rel="prefetch" href="/notebook/assets/js/54.543f990e.js"><link rel="prefetch" href="/notebook/assets/js/55.02863756.js"><link rel="prefetch" href="/notebook/assets/js/56.262a1288.js"><link rel="prefetch" href="/notebook/assets/js/57.a80801ee.js"><link rel="prefetch" href="/notebook/assets/js/58.38d623bc.js"><link rel="prefetch" href="/notebook/assets/js/59.07a6b6b6.js"><link rel="prefetch" href="/notebook/assets/js/6.77dfe150.js"><link rel="prefetch" href="/notebook/assets/js/60.df11d23d.js"><link rel="prefetch" href="/notebook/assets/js/61.764a5b2e.js"><link rel="prefetch" href="/notebook/assets/js/62.28916805.js"><link rel="prefetch" href="/notebook/assets/js/63.f54fb2ba.js"><link rel="prefetch" href="/notebook/assets/js/64.73bb9e27.js"><link rel="prefetch" href="/notebook/assets/js/65.8e45d2c8.js"><link rel="prefetch" href="/notebook/assets/js/66.6cabc639.js"><link rel="prefetch" href="/notebook/assets/js/67.61f4e99c.js"><link rel="prefetch" href="/notebook/assets/js/68.fec9c74e.js"><link rel="prefetch" href="/notebook/assets/js/69.b530b731.js"><link rel="prefetch" href="/notebook/assets/js/7.bac04506.js"><link rel="prefetch" href="/notebook/assets/js/70.e2902def.js"><link rel="prefetch" href="/notebook/assets/js/71.09df6e0a.js"><link rel="prefetch" href="/notebook/assets/js/72.5c611ac8.js"><link rel="prefetch" href="/notebook/assets/js/73.66c43b39.js"><link rel="prefetch" href="/notebook/assets/js/74.243e6a2f.js"><link rel="prefetch" href="/notebook/assets/js/75.de524cab.js"><link rel="prefetch" href="/notebook/assets/js/76.750c2fc0.js"><link rel="prefetch" href="/notebook/assets/js/77.fa7ddd5d.js"><link rel="prefetch" href="/notebook/assets/js/78.192816fd.js"><link rel="prefetch" href="/notebook/assets/js/79.a3f3fcd9.js"><link rel="prefetch" href="/notebook/assets/js/8.48754361.js"><link rel="prefetch" href="/notebook/assets/js/80.c3fd6acb.js"><link rel="prefetch" href="/notebook/assets/js/81.7ba4627a.js"><link rel="prefetch" href="/notebook/assets/js/82.e355d704.js"><link rel="prefetch" href="/notebook/assets/js/83.2579aea2.js"><link rel="prefetch" href="/notebook/assets/js/84.1f72cccf.js"><link rel="prefetch" href="/notebook/assets/js/85.7874726d.js"><link rel="prefetch" href="/notebook/assets/js/86.a863f0c3.js"><link rel="prefetch" href="/notebook/assets/js/87.c8c7690e.js"><link rel="prefetch" href="/notebook/assets/js/88.5d7963f9.js"><link rel="prefetch" href="/notebook/assets/js/89.9391f30b.js"><link rel="prefetch" href="/notebook/assets/js/9.c2fb6f2c.js"><link rel="prefetch" href="/notebook/assets/js/90.76bedd2e.js"><link rel="prefetch" href="/notebook/assets/js/91.e345e87a.js"><link rel="prefetch" href="/notebook/assets/js/92.175f428e.js"><link rel="prefetch" href="/notebook/assets/js/93.f45b4417.js"><link rel="prefetch" href="/notebook/assets/js/94.e3f459de.js"><link rel="prefetch" href="/notebook/assets/js/95.1632f845.js"><link rel="prefetch" href="/notebook/assets/js/96.4d0a41d5.js"><link rel="prefetch" href="/notebook/assets/js/97.39bd1831.js"><link rel="prefetch" href="/notebook/assets/js/98.54282751.js"><link rel="prefetch" href="/notebook/assets/js/99.b60593a3.js">
    <link rel="stylesheet" href="/notebook/assets/css/0.styles.cee65b40.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/notebook/" class="home-link router-link-active"><!----> <span class="site-name">我的笔记</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/notebook/guide/" class="nav-link">
  指南
</a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/notebook/guide/" class="nav-link">
  指南
</a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>GitFlow工作流指南</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/notebook/gitflow/" aria-current="page" class="sidebar-link">为什么需要版本控制</a></li><li><a href="/notebook/gitflow/什么是Git.html" class="sidebar-link">什么是 Git</a></li><li><a href="/notebook/gitflow/安装Git.html" class="sidebar-link">安装 Git</a></li><li><a href="/notebook/gitflow/Git工作流简介.html" class="sidebar-link">Git 工作流简介</a></li><li><a href="/notebook/gitflow/集中式工作流.html" class="sidebar-link">集中式工作流</a></li><li><a href="/notebook/gitflow/功能分支工作流.html" class="active sidebar-link">功能分支工作流</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/notebook/gitflow/功能分支工作流.html#概述" class="sidebar-link">概述</a></li><li class="sidebar-sub-header"><a href="/notebook/gitflow/功能分支工作流.html#工作方式" class="sidebar-link">工作方式</a></li><li class="sidebar-sub-header"><a href="/notebook/gitflow/功能分支工作流.html#pull-requests" class="sidebar-link">Pull Requests</a></li><li class="sidebar-sub-header"><a href="/notebook/gitflow/功能分支工作流.html#示例" class="sidebar-link">示例</a></li><li class="sidebar-sub-header"><a href="/notebook/gitflow/功能分支工作流.html#总结" class="sidebar-link">总结</a></li></ul></li><li><a href="/notebook/gitflow/GitFlow 工作流.html" class="sidebar-link">GitFlow 工作流</a></li><li><a href="/notebook/gitflow/Forking 工作流.html" class="sidebar-link">Forking 工作流</a></li><li><a href="/notebook/gitflow/Pull Requests.html" class="sidebar-link">Pull Requests</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="功能分支工作流"><a href="#功能分支工作流" class="header-anchor">#</a> 功能分支工作流</h1> <h2 id="概述"><a href="#概述" class="header-anchor">#</a> 概述</h2> <p><img src="/notebook/assets/img/git-workflow-feature-branch-1.8f94b280.png" alt="img"></p> <p>一旦你玩转了集中式工作流，在开发过程中可以很简单地加上功能分支，用来鼓励开发者之间协作和简化交流。</p> <p>功能分支工作流背后的核心思路是所有的功能开发应该在一个专门的分支，而不是在 master 分支上。这个隔离可以方便多个开发者在各自的功能上开发而不会弄乱主干代码。另外，也保证了 master 分支的代码一定不会是有问题的，极大有利于集成环境。</p> <p>功能开发隔离也让 pull requests 工作流成功可能，pull requests 工作流能为每个分支发起一个讨论，在分支合入正式项目之前，给其它开发者有表示赞同的机会。另外，如果你在功能开发中有问题卡住了，可以开一个 pull requests 来向同学们征求建议。这些做法的重点就是，pull requests 让团队成员之间互相评论工作变成非常方便！</p> <h2 id="工作方式"><a href="#工作方式" class="header-anchor">#</a> 工作方式</h2> <p>功能分支工作流仍然用中央仓库，并且 master 分支还是代表了正式项目的历史。但不是直接提交本地历史到各自的本地 master 分支，开发者每次在开始新功能前先创建一个新分支。功能分支应该有个有描述性的名字，比如 animated-menu-items 或 issue-#1061，这样可以让分支有个清楚且高聚焦的用途。</p> <p>在 master 分支和功能分支之间，Git 是没有技术上的区别，所以开发者可以用和集中式工作流中完全一样的方式编辑、暂存和提交修改到功能分支上。</p> <p>另外，功能分支也可以（且应该）push 到中央仓库中。这样不修改正式代码就可以和其它开发者分享提交的功能。由于 master 仅有的一个『特殊』分支，在中央仓库上存多个功能分支不会有任何问题。当然，这样做也可以很方便地备份各自的本地提交。</p> <h2 id="pull-requests"><a href="#pull-requests" class="header-anchor">#</a> Pull Requests</h2> <p>功能分支除了可以隔离功能的开发，也使得通过 Pull Requests 讨论变更成为可能。一旦某个开发完成一个功能，不是立即合并到 master，而是 push 到中央仓库的功能分支上并发起一个 Pull Request 请求去合并修改到 master。在修改成为主干代码前，这让其它的开发者有机会先去 Review 变更。</p> <p>Code Review 是 Pull Requests 的一个重要的收益，但 Pull Requests 目的是讨论代码一个通用方式。你可以把 Pull Requests 作为专门给某个分支的讨论。这意味着可以在更早的开发过程中就可以进行 Code Review。比如，一个开发者开发功能需要帮助时，要做的就是发起一个 Pull Request，相关的人就会自动收到通知，在相关的提交旁边能看到需要帮助解决的问题。</p> <p>一旦 Pull Request 被接受了，发布功能要做的就和集中式工作流就很像了。首先，确定本地的 master 分支和上游的 master 分支是同步的。然后合并功能分支到本地 master 分支并 push 已经更新的本地 master 分支到中央仓库。</p> <h2 id="示例"><a href="#示例" class="header-anchor">#</a> 示例</h2> <p>下面的示例演示了如何把 Pull Requests 作为 Code Review 的方式，但注意 Pull Requests 可以用于很多其它的目的。</p> <h3 id="小红开始开发一个新功能"><a href="#小红开始开发一个新功能" class="header-anchor">#</a> 小红开始开发一个新功能</h3> <p><img src="" alt="img"></p> <p>在开始开发功能前，小红需要一个独立的分支。使用下面的命令新建一个分支：</p> <div class="language-text extra-class"><pre class="language-text"><code>git checkout -b marys-feature master
</code></pre></div><p>这个命令检出一个基于 master 名为 marys-feature 的分支，Git 的 <code>-b</code> 选项表示如果分支还不存在则新建分支。这个新分支上，小红按老套路编辑、暂存和提交修改，按需要提交以实现功能：</p> <div class="language-text extra-class"><pre class="language-text"><code>git status
git add
git commit
</code></pre></div><h3 id="小红要去吃个午饭"><a href="#小红要去吃个午饭" class="header-anchor">#</a> 小红要去吃个午饭</h3> <p><img src="" alt="img"></p> <p>早上小红为新功能添加一些提交。去吃午饭前，push 功能分支到中央仓库是很好的做法，这样可以方便地备份，如果和其它开发协作，也让他们可以看到小红的提交。</p> <div class="language-text extra-class"><pre class="language-text"><code>git push -u origin marys-feature
</code></pre></div><p>这条命令 <code>push marys-feature</code> 分支到中央仓库（origin），<code>-u</code> 选项设置本地分支去跟踪远程对应的分支。设置好跟踪的分支后，小红就可以使用 <code>git push</code> 命令省去指定推送分支的参数。</p> <h3 id="小红完成功能开发"><a href="#小红完成功能开发" class="header-anchor">#</a> 小红完成功能开发</h3> <p><img src="" alt="img"></p> <p>小红吃完午饭回来，完成整个功能的开发。在合并到 master 之前，她发起一个 Pull Request 让团队的其它人知道功能已经完成。但首先，她要确认中央仓库中已经有她最近的提交：</p> <div class="language-text extra-class"><pre class="language-text"><code>git push
</code></pre></div><p>然后，在她的 Git GUI 客户端中发起 Pull Request，请求合并 marys-feature 到 master，团队成员会自动收到通知。Pull Request 很酷的是可以在相关的提交旁边显示评注，所以你可以很对某个变更集提问。</p> <h3 id="小黑收到-pull-request"><a href="#小黑收到-pull-request" class="header-anchor">#</a> 小黑收到 Pull Request</h3> <p><img src="" alt="img"></p> <p>小黑收到了 Pull Request 后会查看 marys-feature 的修改。决定在合并到正式项目前是否要做些修改，且通过 Pull Request 和小红来回地讨论。</p> <h3 id="小红再做修改"><a href="#小红再做修改" class="header-anchor">#</a> 小红再做修改</h3> <p><img src="" alt="img"></p> <p>要再做修改，小红用和功能第一个迭代完全一样的过程。编辑、暂存、提交并push更新到中央仓库。小红这些活动都会显示在 Pull Request 上，小黑可以断续做评注。</p> <p>如果小黑有需要，也可以把 marys-feature 分支拉到本地，自己来修改，他加的提交也会一样显示在 Pull Request 上。</p> <h3 id="小红发布她的功能"><a href="#小红发布她的功能" class="header-anchor">#</a> 小红发布她的功能</h3> <p><img src="" alt="img"></p> <p>一旦小黑可以的接受 Pull Request，就可以合并功能到稳定项目代码中（可以由小黑或是小红来做这个操作）：</p> <div class="language-text extra-class"><pre class="language-text"><code>git checkout master
git pull
git pull origin marys-feature
git push
</code></pre></div><p>无论谁来做合并，首先要检出 master 分支并确认是它是最新的。然后执行 <code>git pull origin marys-feature</code> 合并 marys-feature 分支到和已经和远程一致的本地 master 分支。你可以使用简单 <code>git merge marys-feature</code> 命令，但前面的命令可以保证总是最新的新功能分支。最后更新的 master 分支要重新 push 回到 origin。</p> <p>这个过程常常会生成一个合并提交。有些开发者喜欢有合并提交，因为它像一个新功能和原来代码基线的连通符。但如果你偏爱线性的提交历史，可以在执行合并时 rebase 新功能到 master 分支的顶部，这样生成一个快进（fast-forward）的合并。</p> <p>一些 GUI 客户端可以只要点一下『接受』按钮执行好上面的命令来自动化 Pull Request 接受过程。如果你的不能这样，至少在功能合并到 master 分支后能自动关闭 Pull Request。</p> <h3 id="与此同时-小明在做和小红一样的事"><a href="#与此同时-小明在做和小红一样的事" class="header-anchor">#</a> 与此同时，小明在做和小红一样的事</h3> <p>当小红和小黑在 marys-feature 上工作并讨论她的 Pull Request 的时候，小明在自己的功能分支上做完全一样的事。</p> <p>通过隔离功能到独立的分支上，每个人都可以自主的工作，当然必要的时候在开发者之间分享变更还是比较繁琐的。</p> <h2 id="总结"><a href="#总结" class="header-anchor">#</a> 总结</h2> <p>到了这里，但愿你发现了功能分支可以很直接地在集中式工作流的仅有的 master 分支上完成多功能的开发。另外，功能分支还使用了 Pull Request，使得可以在你的版本控制 GUI 客户端中讨论某个提交。</p> <p>功能分支工作流是开发项目异常灵活的方式。问题是，有时候太灵活了。对于大型团队，常常需要给不同分支分配一个更具体的角色。GitFlow 工作流是管理功能开发、发布准备和维护的常用模式。</p></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2021/4/17 下午5:59:44</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/notebook/gitflow/集中式工作流.html" class="prev">
        集中式工作流
      </a></span> <span class="next"><a href="/notebook/gitflow/GitFlow 工作流.html">
        GitFlow 工作流
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----></div></div>
    <script src="/notebook/assets/js/app.400f01da.js" defer></script><script src="/notebook/assets/js/2.ffba27f2.js" defer></script><script src="/notebook/assets/js/14.3ed225c4.js" defer></script>
  </body>
</html>
